朗伯定理

Shader "Shenjun/FragmentLight_Specular" {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _BumpTex ("Bump", 2D) = ""{}
            _SpecularColor ("SpecularColor", Color) = (1,1,1,1)
            _Shininess ("Shininess", float) = 10.0
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 200

            Pass
            {
                Tags { "LightMode"="ForwardBase" }

                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                #include "Lighting.cginc"

                sampler2D _MainTex;
                sampler2D _BumpTex;
                float4 _SpecularColor;
                float _Shininess;

                struct v2f
                {
                    float4 pos : POSITION;
                    fixed2 uv : TEXCOORD;
                    float3 normalWorld : TEXCOORD1;
                    float3 posWorld : TEXCOORD2;
                    float4 tangentWorld : TEXCOORD3;
                };

                v2f vert(appdata_tan input)
                {
                    v2f o;
                    o.pos = mul(UNITY_MATRIX_MVP, input.vertex);
                    o.uv = input.texcoord;
                    o.normalWorld = mul((float3x3)_Object2World, input.normal);
                    o.posWorld = mul(_Object2World, input.vertex);
                    o.tangentWorld = mul(_Object2World, input.tangent);
                    return o;
                } 

                void frag(v2f input, out float4 col : COLOR)
                {
                    col = tex2D(_MainTex, input.uv);

                    // 计算法线的效果
                    //float4 encodeNormal = tex2D(_BumpTex, input.uv);
                    //float3 localTexcoord = float3(2 * encodeNormal.a - 1, 2 * encodeNormal.g - 1, 0);
                    //localTexcoord.z = sqrt(1 - dot(localTexcoord, localTexcoord));
                    //float3 biNormalDir = cross (input.normalWorld, input.tangentWorld * input.tangentWorld.w);
                    //float3x3 TBN = float3x3((float3)input.tangentWorld, biNormalDir, input.normalWorld);
                    //float3 N = normalize(mul(localTexcoord, TBN));


                    float3 N = UnpackNormal(tex2D(_BumpTex, input.uv));
                    // diffuseColor = C * max(0, dot(N, L))
    //                float3 N = normalize(input.normalWorld);
                    float3 L;
                    float atten;
                    if(_WorldSpaceLightPos0.w == 0)
                    {
                        atten = 1;
                        L = normalize(_WorldSpaceLightPos0);
                    }
                    else
                    {
                        float3 vertex2Light = _WorldSpaceLightPos0.xyz - input.posWorld;
                        L = normalize(vertex2Light);
                        float fLenght = length(vertex2Light);
                        atten = 1 / fLenght;
                    }

                    float3 C = atten * _LightColor0.rgb;

                    float3 diffuseColor = C * max(0, dot(N, L));

                    float3 R = normalize(reflect(-L, N));
                    float3 V = normalize(_WorldSpaceCameraPos.xyz - input.posWorld);

                    float3 SpecularColor = C * _SpecularColor.rgb * pow(max(0, dot(R, V)), _Shininess);

                    col.rgb *= diffuseColor;
                    col.rgb += SpecularColor;
                }


                ENDCG
            } // end pass
        } 
        FallBack "Diffuse"
    }

阴影渲染


Shader "Shenjun/Diffuse" 
{
    Properties 
    {
        _DiffuseTexture ("Diffuse Texture", 2D) = "white" {}
        _DiffuseTint ( "Diffuse Tint", Color) = (1, 1, 1, 1)
    }

    SubShader 
    {
        Tags { "RenderType"="Opaque" }

        pass
        {        
            Tags { "LightMode"="ForwardBase"}

            CGPROGRAM

            #pragma target 3.0
            #pragma fragmentoption ARB_precision_hint_fastest

            #pragma vertex vertShadow
            #pragma fragment fragShadow
            #pragma multi_compile_fwdbase

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"

            sampler2D _DiffuseTexture;
            float4 _DiffuseTint;
            float4 _LightColor0;

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 lightDir : TEXCOORD0;
                float3 normal : TEXCOORD1;
                float2 uv : TEXCOORD2;
                LIGHTING_COORDS(3, 4)
            };

            v2f vertShadow(appdata_base v)
            {
                v2f o;

                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = v.texcoord;
                o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
                o.normal = normalize(v.normal).xyz;

                TRANSFER_VERTEX_TO_FRAGMENT(o);

                return o; 
            }

            float4 fragShadow(v2f i) : COLOR
            {                    
                float3 L = normalize(i.lightDir);
                float3 N = normalize(i.normal);     

                float attenuation = LIGHT_ATTENUATION(i) * 2;
                float4 ambient = UNITY_LIGHTMODEL_AMBIENT * 2;

                float NdotL = saturate(dot(N, L));
                float4 diffuseTerm = NdotL * _LightColor0 * _DiffuseTint * attenuation;

                float4 diffuse = tex2D(_DiffuseTexture, i.uv);

                float4 finalColor = (ambient + diffuseTerm) * diffuse;

                return finalColor;
            }

            ENDCG
        }        

    } 
    FallBack "Diffuse"
}